//
//  JJBaseRequest.swift
//  swiftStudy
//
//  Created by hamilyjing on 2020/6/25.
//  Copyright © 2020 JJ. All rights reserved.
//

import Foundation

import Alamofire

class JJBaseRequest {
    var request: Request?
    var requestMethod: HTTPMethod = .get
    var requestParameters: [String: Any]?
    
    var response: HTTPURLResponse?
    var responseString: String?
    var responseError: Error?
    var responseStatusCode: Int? {
        if let response = response {
            return response.statusCode
        } else {
            return nil
        }
    }
    var responseHeaders: [String: String]? {
        if let response = response {
            var headers = [String: String]()
            for (field, value) in response.allHeaderFields {
                headers["\(field)"] = "\(value)"
            }
            return headers
        } else {
            return nil
        }
    }
    
    var otherInfo = [String: Any]()
    
    var successCompletionBlock: ((JJBaseRequest, Any?) -> Void)?
    var failureCompletionBlock: ((JJBaseRequest) -> Void)?
    
    func host() -> String {
        return ""
    }
    
    func path() -> String {
        return ""
    }
    
    func buildRequestURL() -> String {
        let urlString = host() + path()
        return urlString
    }
    
    open func parameters() -> [String: Any]? {
        return requestParameters
    }
    
    func headers() -> [String: String]? {
        return nil
    }
    
    func timeoutInterval() -> TimeInterval {
        return 30
    }
    
    func start() -> Void {
        stop()
        
        SessionManager.default.session.configuration.timeoutIntervalForRequest = timeoutInterval()
        
        let request = Alamofire.request(buildRequestURL(), method: requestMethod, parameters: parameters(), encoding: URLEncoding.default, headers: headers())
        self.request = request
        
        request.responseString { response in
            self.handleRequestResult(response.response, response.result)
        }
    }
    
    func start(successCompletionBlock successCompletionBlock_: ((JJBaseRequest, Any?) -> Void)?, failureCompletionBlock failureCompletionBlock_: ((JJBaseRequest) -> Void)?) -> Void {
        successCompletionBlock = successCompletionBlock_
        failureCompletionBlock = failureCompletionBlock_
        
        start()
    }
    
    func stop() -> Void {
        request?.cancel()
    }
    
    func handleRequestResult(_ response_: HTTPURLResponse?, _ result_: Result<String>) {
        response = response_
        
        let succeed = checkResponseResult()
        if succeed {
            responseString = filterResponseString(result_.value)
            if (responseString != nil) {
                otherInfo["responseString"] = responseString!
            }
            
            let model = requestSuccessedFilter()
            if let successCompletionBlock = self.successCompletionBlock {
                successCompletionBlock(self, model)
            }
        } else {
            responseString = result_.value
            if (responseString != nil) {
                otherInfo["responseString"] = responseString!
            }
            responseError = result_.error
            
            requestFailFilter()
            if let failureCompletionBlock = self.failureCompletionBlock {
                failureCompletionBlock(self)
            }
        }
    }
    
    func checkResponseResult() -> Bool {
        guard responseStatusCode != nil else {
            return false
        }
        
        let statusCode = responseStatusCode!
        if statusCode >= 200 && statusCode <= 299 {
            return true
        } else {
            return false
        }
    }
    
    func filterResponseString(_ responseString_: String?) -> String? {
        return responseString_
    }
    
    func requestSuccessedFilter() -> Any? {
        return nil
    }
    
    func requestFailFilter() {
    }
    
    func clearCompletionBlock() -> Void {
        successCompletionBlock = nil
        failureCompletionBlock = nil
    }
}
